package com.helloniu.wb.tools {

import com.helloniu.data.wb.WBStyle;
import com.helloniu.data.wb.info.ShapeInfo;
import com.helloniu.fl.util.Tool;
import com.helloniu.wb.CursorManager2;
import com.helloniu.wb.containers.BlankPaperWrapper;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import mx.core.UIComponent;

public class DrawingTool extends UIComponent {
	public function getCurrWBStyle():WBStyle {
		return (parent as BlankPaperWrapper).getWBStyle();
	}

    protected function resetDefaultWBStyle():void {
    }

    public function setWBStyle(awbstyle:WBStyle, styleChanged:Boolean=true):void {
    	this.shapeInfo.styleChanged = styleChanged;
        this.shapeInfo.style = awbstyle;
    }

    public function setShapeType(ashapeType:Number):void {
        this.shapeInfo.shapeType = ashapeType;
    }

    public function getWBStyle():WBStyle {
        return shapeInfo.style;
    }

    public function setShapeInfo(ashapeInfo:ShapeInfo):void {
        this.shapeInfo = ashapeInfo;
    }

    public function getShapeInfo():ShapeInfo {
        return shapeInfo;
    }

    public function getToolType():Number {
    	// @temp tonyy, return (parent as WB).getToolType();
        return -1;
    }

    private var dinfo:DrawingToolInfo = null;
    public function setInfo(ainfo:DrawingToolInfo):void {
        this.dinfo = ainfo;
    }

    public function getInfo():DrawingToolInfo {
        return dinfo;
    }

    public function getShapePoints2():Array {
        return getShapePoints();
    }

    public function getShapePoints():Array {
        return shapeInfo.shapeRawData;
    }

    public function setShapePoints(arr:Array):void {
    	shapeInfo.shapeRawData = arr;
    }

    public function addStartXY(addx:Number, addy:Number):void {
        var sp:Point = getStartPoint();
        var spX:Number = sp.x + addx;
        var spY:Number = sp.y + addy;

        setStartPoint(new Point(spX, spY), false);
    }

    public function setStartPoint(astartP:Point, resetArr:Boolean = true):void {
        if(resetArr) {
            shapeInfo.shapeRawData = new Array();
        }

        shapeInfo.shapeRawData[0] = astartP;
    }

    public function getStartPoint():Point {
    	return shapeInfo.shapeRawData[0] as Point;
    }

    public function addEndXY(addx:Number, addy:Number):void {
        var ep:Point = getEndPoint();
        var epX:Number = ep.x + addx;
        var epY:Number = ep.y + addy;

        setEndPoint(new Point(epX, epY), false);
    }

    public function setEndPoint(endP:Point, appendEnd:Boolean = true):void {
        if(appendEnd) {
            shapeInfo.shapeRawData.push(endP);
        }
        else {
            shapeInfo.shapeRawData[shapeInfo.shapeRawData.length - 1] = endP;
        }
    }

    public function getEndPoint():Point {
    	return shapeInfo.shapeRawData[shapeInfo.shapeRawData.length - 1]  as Point;
    }

    public function get isDragging():Boolean {
        if(systemManager.hasEventListener(MouseEvent.MOUSE_MOVE)) {
            return true;
        }
        else {
            return false;
        }
    }

    public function set isSelected(val:Boolean):void {
        this._isSelected = val;

        if(val) {
            (this.parent as BlankPaperWrapper).selectedItem = this;
        }
        else {
            // @temp tonyy
            // hide the resize handler
            (this.parent as BlankPaperWrapper).selectedItem = null;
        }
    }

    public function get isSelected():Boolean {
        return (this.parent as BlankPaperWrapper).selectedItem == this;
    }

    public function DrawingTool() {
        super();

        shapeInfo = new ShapeInfo();

        setupStyles();
    }

    public function setupStyles():void{
    	// @temp tonyy
    }

    public function setupListeners():void {
        //need to set up events
        //addEventListener(MouseEvent.CLICK, clickHandler);
        addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
        addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
        addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
        addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
    }

    public function isPainting():Boolean {
        return CursorManager2.isPainting();
    }

    /**
     * Listens for mouseDown
     **/
    //[Event(name="mouseDown", type="flash.events.MouseEvent")]
    public function mouseDownHandler(event:MouseEvent):void {
        if(isPainting()) {
            return;
        }

        // @temp tonyy
        CursorManager2.removeCursor();

        // @temp tonyy , modify shape of youself!
        /*
        if(getInfo().shapeOwner != ContextManager.getInstance().getUID()) {
            return;
        }
        */

        if(CursorManager2.getToolType() == CursorManager2.PAINT_NONE) {
            return;
        }

        if(CursorManager2.getToolType() == CursorManager2.PAINT_LASER) {
            return;
        }

        isSelected = !isSelected;

        if(CursorManager2.getToolType() == CursorManager2.MOVE_TOOL) {
            CursorManager2.setCursor(CursorManager2.MOVE_CURSOR);
        }

        //stop propogation so the BlankPaperWrapper doesn't listen and
        //act on the mouseDown event
        event.stopPropagation();

        //lc = getStyle('mouseDownColor');
        //adjust our move x and y's
        // event.localX: The horizontal coordinate at which the event occurred relative to the containing sprite.
        moveStartX = event.localX;
        moveStartY = event.localY;

        moveEndX = event.localX;
        moveEndY = event.localY;
        moveDistanceX = 0;
        moveDistanceY = 0;

        startDragging(event);

        repaint();
    }

    /**
     * Listens for mouseLeave
     **/
    //[Event(name="mouseLeave", type="flash.events.MouseEvent")]
    protected function mouseLeaveHandler(event:MouseEvent):void {
        stopDragging();

        if(CursorManager2.getToolType() == CursorManager2.MOVE_TOOL) {
            CursorManager2.removeCursor();
        }
    }

    /**
     * Listens for mouseMove
     **/
    ///[Event(name="mouseMove", type="flash.events.MouseEvent")]
    public function mouseMoveHandler(event:MouseEvent):void {
        if(isPainting()) {
            return;
        }

        var pt:Point = new Point(event.stageX,event.stageY);
        pt = globalToLocal(pt);

        moveEndX = pt.x;
        moveEndY = pt.y;

        // we need to re-adjust our start x & y and end x & y

        moveDistanceX = moveEndX - moveStartX;
        moveDistanceY = moveEndY - moveStartY;

        //adjust our start variables again after we
        //have changed the moveDistance vars
        moveStartX = moveEndX;
        moveStartY = moveEndY;

        resetMoveVars();

        // @temp tonyy, not good some times
        // check if drawingtool is outof the wb
        if(isDTOutofWB()) {
            return;
        }

        repaint();
    }

    protected function isDTOutofWB():Boolean {
        if(this.parent.mouseX < 2 || this.parent.mouseY < 2) {
            return true;
        }

        if((this.parent.mouseX ) > this.parent.width ||
           (this.parent.mouseY ) > this.parent.height)
        {
            return true;
        }

        return false;
    }

    protected function repaint():void {
    }

    /**
     * Listens for mouseOver
     **/
    //[Event(name="mouseOver", type="flash.events.MouseEvent")]
    public function mouseOverHandler(event:MouseEvent):void {
//Tool.traceT("===mouse over==: " + isDragging2 +"|"+ isSelected);
        if((CursorManager2.getToolType() == CursorManager2.MOVE_TOOL) &&
            !isDragging2 && isSelected) {
            CursorManager2.setCursor(CursorManager2.MOVE_CURSOR);
        }
    }

    /**
     * Listens for mouseOut
     **/
    //[Event(name="mouseOut", type="flash.events.MouseEvent")]
    public function mouseOutHandler(event:MouseEvent):void {
        if((CursorManager2.getToolType() == CursorManager2.MOVE_TOOL) &&
            !isDragging2 && isSelected)
        {
            CursorManager2.removeCursor();
        }
    }

    /**
     * Listens for mouseUp
     **/
    [Event(name="mouseUp", type="flash.events.MouseEvent")]
    public function mouseUpHandler(event:MouseEvent):void {
        if(isPainting()) {
            return;
        }

        if(CursorManager2.getToolType() == CursorManager2.PAINT_NONE) {
            return;
        }

        if(CursorManager2.getToolType() == CursorManager2.PAINT_LASER) {
            return;
        }

        if(isDragging) {
            this.resetMoveVars();

            // @temp tonyy, to be redesign
            /*
            // add to history
            var undoObj:UndoableObject = new UndoableObject();
            undoObj.type = "setShapePoints";
            undoObj.owner = this;
            undoObj.undoType = "setShapePoints";
            undoObj.undoParam = cloneArray(getShapePoints());
            undoObj.redoType = "setShapePoints";
            undoObj.redoParam = cloneArray(getShapePoints());
            UndoManager.addUndoable(undoObj);
            */
        }

        stopDragging();

        // no change
        if(moveDistanceX == 0 && moveDistanceY == 0) {
            return;
        }

        repaint();

        if(event.currentTarget == this) {
            // user interaction-notifyModelInfoChanged, modify shape
            //(parent as BlankPaperWrapper).fireChangeShapeEvent(this);
            // @temp tonyy, event
            // fire ModifyEvent
            Tool.traceT("--ModifyEvent:" + moveDistanceX +"|"+ moveDistanceY +"|"+ this);

        }
    }

    // shallow
    private function cloneArray(arr:Array):Array {
        var narr:Array = new Array();

        for(var i :int = 0; i < arr.length; i++) {
            narr.push(arr[i]);
        }

        return narr;
    }

    protected function startDragging(event:MouseEvent):void {
        isDragging2 = true;
        systemManager.addEventListener(
            MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);

        systemManager.addEventListener(
            MouseEvent.MOUSE_UP, mouseUpHandler, true);

        systemManager.stage.addEventListener(
            Event.MOUSE_LEAVE, mouseLeaveHandler);
    }

    protected function stopDragging():void {
        isDragging2 = false;
        systemManager.removeEventListener(
            MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);

        systemManager.removeEventListener(
            MouseEvent.MOUSE_UP, mouseUpHandler, true);

        systemManager.stage.removeEventListener(
            Event.MOUSE_LEAVE, mouseLeaveHandler);
    }

    protected function resetMoveVars():void{
        addStartXY(moveDistanceX, moveDistanceY);
        addEndXY(moveDistanceX, moveDistanceY);
    }

	// get shape raw data
    protected function get shapeRawData():Array {
        return shapeInfo.shapeRawData;
    }

	private var shapeInfo:ShapeInfo = null;

    protected var isDragging2:Boolean = false;
    protected var moveStartX:Number;
    protected var moveStartY:Number;
    protected var moveEndX:Number;
    protected var moveEndY:Number;
    protected var moveDistanceX:Number = 0;
    protected var moveDistanceY:Number = 0;
    private var _isSelected:Boolean;
}
}